package com.tuling.dynamicthreadpooldemo.threadpool;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.listener.Listener;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.alibaba.fastjson.JSONObject;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;


@Configuration
@Data
public class MyDynamicThreadPool implements InitializingBean {

    @Value("${threadPool.corePoolSize}")
    private int corePoolSize;
    @Value("${threadPool.maxPoolSize}")
    private int maxPoolSize;
    @Value("${threadPool.queueCapacity}")
    private int queueCapacity;
    @Value("${threadPool.keepAliveSeconds}")
    private int keepAliveSeconds;

    private static ThreadPoolTaskExecutor threadPoolTaskExecutor;


    @Autowired
    private NacosConfigManager nacosConfigManager;

    @Autowired
    private NacosConfigProperties nacosConfigProperties;


    @Override
    public void afterPropertiesSet() throws Exception {
        threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        threadPoolTaskExecutor.setThreadNamePrefix("Fox--");
        threadPoolTaskExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println("队列已满，丢弃任务");
            }
        });
        threadPoolTaskExecutor.initialize();
        nacosConfigManager.getConfigService().addListener("threadPool.yml", nacosConfigProperties.getGroup(), new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }

            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("动态修改前-->");
                print();
                Yaml yaml = new Yaml();
                InputStream inputStream = new ByteArrayInputStream(configInfo.getBytes());
                Map<String, Object> dataMap = yaml.load(inputStream);
                // 将Map转换为JSONObject
                JSONObject pool = new JSONObject(dataMap).getJSONObject("threadPool");
                threadPoolTaskExecutor.setCorePoolSize(pool.getInteger("corePoolSize"));
                threadPoolTaskExecutor.setMaxPoolSize(pool.getInteger("maxPoolSize"));
                threadPoolTaskExecutor.setQueueCapacity(pool.getInteger("keepAliveSeconds"));
                threadPoolTaskExecutor.setQueueCapacity(pool.getInteger("queueCapacity"));
                System.out.println("动态修改后-->");
                print();
            }
        });

    }

    //执行任务
    public void execute(Runnable runnable) {
        threadPoolTaskExecutor.execute(runnable);
    }

    public void print() {
        System.out.println("核心线程数：" + threadPoolTaskExecutor.getThreadPoolExecutor().getCorePoolSize() + " " + "最大线程数：" + threadPoolTaskExecutor.getThreadPoolExecutor().getMaximumPoolSize() + " " + "阻塞队列数：" + threadPoolTaskExecutor.getThreadPoolExecutor().getQueue().size() + "/" + queueCapacity + " " + "活跃线程数：" + threadPoolTaskExecutor.getThreadPoolExecutor().getActiveCount());
    }
}